﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Xml.Serialization;

namespace Lyon.Updater
{
    [Serializable]
    [XmlTypeAttribute(Namespace = "http://schemas.microsoft.com/pag/cab-command-map")]
    [XmlRootAttribute(Namespace = "http://schemas.microsoft.com/pag/cab-command-map", IsNullable = false)]
    public class UpdateInfo
    {
        static string ConfigFileName = "UpdateConfig.xml";

        static public void LoadWebFile(string url, string path)
        {
            using (FileStream fileStream = File.Open(path, FileMode.Create, FileAccess.Write))
            {
                WebRequest request = WebRequest.Create(url);
                using (WebResponse response = request.GetResponse())
                {
                    using (Stream respStream = response.GetResponseStream())
                    {
                        while (fileStream.Position < response.ContentLength)
                        {
                            byte[] buffer = new byte[1024 * 4];
                            int length = respStream.Read(buffer, 0, buffer.Length);
                            fileStream.Write(buffer, 0, length);
                        }
                    }
                }
            }
        }

        static public UpdateInfo LoadInfo(string updateUrl, object version)
        {
            string url = String.Format(@"{0}/{1}", updateUrl, ConfigFileName);
            string path = String.Format(@"{0}\{1}", AppDomain.CurrentDomain.BaseDirectory, ConfigFileName);

            LoadWebFile(url, path);

            UpdateInfo updateInfo;
            using (Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(UpdateInfo));
                updateInfo = (UpdateInfo)serializer.Deserialize(stream);
            }

            File.Delete(path);

            updateInfo.LastUpdateDate = version == null ? DateTime.MinValue : (DateTime)version;
            return updateInfo;
        }

        DateTime LastUpdateDate;
        List<UpdateItem> _UpdateItems = new List<UpdateItem>();

        [XmlElementAttribute("UpdateItem")]
        public UpdateItem[] UpdateItems
        {
            get { return _UpdateItems.ToArray(); }
            set
            {
                _UpdateItems.Clear();
                _UpdateItems.AddRange(value);
                _UpdateItems.Sort();
            }
        }

        public UpdateItem[] Installing
        {
            get
            {
                List<UpdateItem> list =_UpdateItems.FindAll(delegate(UpdateItem item)
                {
                    return item.PublishDate > LastUpdateDate;
                });
                return list.ToArray();
            }
        }

        public bool HasInstalling
        {
            get { return Installing.Length > 0; }
        }
    }

    /// <summary>
    /// 更新项。
    /// </summary>
    [Serializable]
    [XmlTypeAttribute(Namespace = "http://schemas.microsoft.com/pag/cab-command-map")]
    public class UpdateItem : IComparable<UpdateItem>
    {
        string _UpdateID;
        string _Content;
        string _FileSize;
        DateTime _PublishDate;

        public object Version
        {
            get
            {
                return _PublishDate;
            }
        }
        /// <summary>
        /// 更新编号
        /// </summary>
        [XmlAttribute]
        public string FileName
        {
            get { return _UpdateID; }
            set { _UpdateID = value; }
        }
        /// <summary>
        /// 详细内容
        /// </summary>
        [XmlAttribute]
        public string Content
        {
            get { return _Content; }
            set { _Content = value; }
        }
        /// <summary>
        /// 文件大小
        /// </summary>
        [XmlAttribute]
        public string FileSize
        {
            get { return _FileSize; }
            set { _FileSize = value; }
        }
        /// <summary>
        /// 发布日期
        /// </summary>
        [XmlAttribute]
        public DateTime PublishDate
        {
            get { return _PublishDate; }
            set { _PublishDate = value; }
        }

        public int CompareTo(UpdateItem other)
        {
            if (other == null)
                return System.Collections.Comparer.Default.Compare(_PublishDate, null);
            return System.Collections.Comparer.Default.Compare(_PublishDate, other._PublishDate);
        }
    }
}